package com.yzpass.api.security;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.yzpass.api.common.Result;
import com.yzpass.api.common.config.YzConfig;
import com.yzpass.api.common.util.JwtUtil;
import jakarta.annotation.Resource;
import jakarta.servlet.*;
import jakarta.servlet.annotation.WebFilter;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Set;
import java.util.UUID;

@WebFilter(urlPatterns = "/*")
@Component
@Slf4j
public class AuthFilter implements Filter {
    @Resource
    YzConfig yzConfig;

    @Resource
    UserPermissionService userPermissionService;

    @Resource
    ObjectMapper objectMapper;

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        // 初始化方法，在过滤器初始化时调用，可以进行一些初始化操作，如加载配置文件等
    }
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        if(servletRequest instanceof HttpServletRequest request){
            String uri = request.getRequestURI();
            if(uri.startsWith("/api/") && !uri.startsWith("/api/anonymous/")){
                //这里检查请求头中的令牌（Token）是否有效
                if(!tokenCheck(request) && servletResponse instanceof HttpServletResponse response){
                    response.setStatus(401);
                    response.setContentType("application/json");
                    response.setCharacterEncoding(StandardCharsets.UTF_8.name());
                    String body = objectMapper.writeValueAsString(Result.warn("login required."));
                    response.getWriter().write(body);
                    return;
                }
            }

        }
        // 过滤方法，在这里可以对请求进行处理，然后决定是否将请求传递给下一个过滤器或控制器
        filterChain.doFilter(servletRequest, servletResponse);
    }

    private boolean tokenCheck(HttpServletRequest request) {
        String auth = request.getHeader("Authorization");
        String head ="Bearer";
        if(auth.startsWith(head) || auth.startsWith(head.toLowerCase())){
            auth = auth.substring(head.length()).trim();
        }

        var opt = JwtUtil.verify(auth,yzConfig.getPublicKey());
        if(opt.isPresent()){
            regPermission(opt.get().userId(),request);
        }
        return opt.isPresent();
    }

    private void regPermission(UUID userId,HttpServletRequest request) {
        Set<String> set = userPermissionService.getPemissionSet(userId);
        var attr = RequestContextHolder.getRequestAttributes();
        if(attr!=null){
            log.info("permissions: {}",set);
            attr.setAttribute("permissions",set, RequestAttributes.SCOPE_REQUEST);
        }
    }

    @Override
    public void destroy() {
        // 销毁方法，在过滤器销毁时调用，可以进行一些资源释放等
    }
}
